﻿#include"XQPython.hpp"
#include<QDebug>
#undef slots
#include"Python.h"
QString XQPython::m_PythonHome;
XQPython::XQPython(QObject* parent)
    :QObject(parent)
{
    init();
}

XQPython::XQPython(const QString& pythonHome, QObject* parent)
	:QObject(parent)
{
	m_PythonHome = pythonHome;
	init();
}

XQPython::~XQPython()
{
	/*PyDECREF(m_pModule);
	m_pModule = nullptr;
	PyDECREF(m_pValue);
	m_pValue = nullptr;
	PyDECREF(m_threadState);
	m_threadState= nullptr;*/
    if (Py_IsInitialized()) {
        //python环境的销毁，与Py_Initialize()对应
        Py_Finalize();
    }
}

QString XQPython::pythonHome() 
{
    return m_PythonHome;
}

void XQPython::setPythonHome(const QString& pythonHome)
{
	m_PythonHome = pythonHome;
}

void XQPython::addCodePath(const QString& path)
{
    PyRun_SimpleString(QString("sys.path.append(r'%1')").arg(path).toLocal8Bit().data());
}

void XQPython::clearCodePath()
{
    PyRun_SimpleString("sys.path.clear()");
}

bool XQPython::setPythonFileName(const QString& name)
{
    m_pModule= PyImport_ImportModule(name.toLocal8Bit().data());
    return m_pModule!=nullptr;
}

bool XQPython::runFunc(const QString& funcName, const QVariantList& Args)
{
	//加载调用的函数
	PyObject* pFunction = PyObject_GetAttrString(m_pModule, funcName.toUtf8().data());
	if (pFunction == NULL) {
		 PyErr_Print();
		return false;
	}
	if (m_pValue != nullptr)
	{
		PyDECREF(m_pValue);//清理上次的
		m_pValue = nullptr;
	}
	// 需要传入的参数
	if(!Args.isEmpty())
	{
		PyObject* pArgs = PyTuple_New(Args.size());
		for (size_t i = 0; i < Args.size(); i++)
		{
			auto type = Args[i].type();
			if (type == QVariant::Type::Bool)
				PyTuple_SetItem(pArgs, i, PyBool_FromLong(Args[i].toBool()));
			else if (type == QVariant::Type::String)
				PyTuple_SetItem(pArgs, i, Py_BuildValue("s", Args[i].toString().toUtf8().data()));
			else if (type == QVariant::Type::Int)
				PyTuple_SetItem(pArgs, i, Py_BuildValue("i", Args[i].toInt()));
			else if (type == QVariant::Type::LongLong)
				PyTuple_SetItem(pArgs, i, Py_BuildValue("L", Args[i].toLongLong()));
			else if (type == QVariant::Type::Double || type == 38)
				PyTuple_SetItem(pArgs, i, Py_BuildValue("f", Args[i].toDouble()));
		}
		m_pValue = PyObject_CallObject(pFunction, pArgs);
		PyDECREF(pArgs);
	}
	else
	{
		m_pValue = PyObject_CallObject(pFunction, NULL);
	}
	/* 释放资源 */
	PyDECREF(pFunction);
	if (m_pValue == nullptr)
		return false;
	return true;
}

bool XQPython::getReturnBool()
{
	return getReturnValue().toBool();
}

int XQPython::getReturnInt()
{
	return getReturnValue().toInt();
}

qint64 XQPython::getReturnLongLong()
{
	return getReturnValue().toLongLong();
}

double XQPython::getReturnDouble()
{
	return getReturnValue().toDouble();
}

QString XQPython::getReturnString()
{
	return getReturnValue().toString();
}

QVariantList XQPython::getReturnList()
{
	return std::move(getReturnValue().toList());
}

QVariantList XQPython::getReturnTuple()
{
	return std::move(getReturnValue().toList());
}

QVariant XQPython::getReturnValue()
{
	return getReturnValue(m_pValue);
}

bool XQPython::getReturnValue(const QString& format, void* ptr)
{
	return m_PyArg_Parse(m_pValue, format.toUtf8().data(), ptr) == 0;
}

